package com.ncmmall.api.apis.mall;

import com.ncmmall.api.apis.service.Result;
import com.ncmmall.api.security.Securitys;
import com.ncmmall.application.business.deliveryaddress.DeliveryAddressApplication;
import com.ncmmall.domain.business.deliveryaddress.DeliveryAddress;
import com.ncmmall.domain.business.deliveryaddress.QDeliveryAddress;
import com.ncmmall.domain.business.merchant.freight.MerchantFreightArea;
import com.ncmmall.domain.business.merchant.freight.MerchantFreightCity;
import com.ncmmall.domain.business.merchant.freight.MerchantFreightProvince;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;

/**
 * 收货地址API
 *
 * @author likaikai
 * @date 2019-07-14 19:41
 */
@RestController
@RequestMapping("/deliveryAddress")
public class DeliveryAddressApi {

    private Logger logger = LoggerFactory.getLogger(DeliveryAddressApi.class);

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private DeliveryAddressApplication deliveryAddressApplication;

    /**
     * 收货地址列表
     *
     * @param request
     * @return
     */
    @GetMapping("/list")
    public Result list(HttpServletRequest request) {
        Result result = new Result();
        try {
            WebUser member = Securitys.user(request);
            List<DeliveryAddress> deliveryAddresses = queryChannelService.queryAllEntity("select * from mall_delivery_address where member_id = :mid order by defaultAddress desc ", ImmutableMap.of("mid", member.getId()), DeliveryAddress.class);
            return result.ok().inject(deliveryAddresses);
        } catch (Exception e) {
            logger.error("[获取收货地址列表异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 收货地址详情
     *
     * @param request
     * @return
     */
    @GetMapping("/detail")
    public Result detail(HttpServletRequest request, long id) {
        Result result = new Result();
        try {
            WebUser member = Securitys.user(request);
            DeliveryAddress deliveryAddress = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(member.getId()).and(QDeliveryAddress.deliveryAddress.id.eq(id)), DeliveryAddress.class);

            if (deliveryAddress == null) {
                return result.fail().setMsg("地址不存在");
            }

            return result.ok().inject(deliveryAddress);

        } catch (Exception e) {
            logger.error("[获取收货地址详情异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 删除收货地址
     *
     * @param request
     * @return
     */
    @DeleteMapping("/remove")
    public Result remove(HttpServletRequest request, long id) {
        Result result = new Result();
        try {
            WebUser member = Securitys.user(request);
            DeliveryAddress deliveryAddress = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(member.getId()).and(QDeliveryAddress.deliveryAddress.id.eq(id)), DeliveryAddress.class);

            if (deliveryAddress == null) {
                return result.fail().setMsg("收货地址不存在");
            }

            deliveryAddressApplication.remove(deliveryAddress);

            return result.ok();

        } catch (Exception e) {
            logger.error("[删除收货地址异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 创建收货地址
     *
     * @param request
     * @return
     */
    @PostMapping("/create")
    public Result create(HttpServletRequest request, @RequestBody DeliveryAddress address) {
        Result result = new Result();
        try {

            WebUser member = Securitys.user(request);
            address.setMember(member);

            if (address.isDefaultAddress()) {
                DeliveryAddress oldDefault = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(member.getId()).and(QDeliveryAddress.deliveryAddress.defaultAddress.eq(true)), DeliveryAddress.class);
                if (oldDefault != null) {
                    deliveryAddressApplication.create(address, oldDefault);
                    return result.ok();
                }
            }

            deliveryAddressApplication.create(address);
            return result.ok();

        } catch (Exception e) {
            logger.error("[创建收货地址异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 修改收货地址
     *
     * @param request
     * @return
     */
    @PutMapping("/modify")
    public Result modify(HttpServletRequest request, @RequestBody DeliveryAddress params) {
        Result result = new Result();
        try {

            WebUser member = Securitys.user(request);

            DeliveryAddress deliveryAddress = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(member.getId()).and(QDeliveryAddress.deliveryAddress.id.eq(params.getId())), DeliveryAddress.class);
            if (deliveryAddress == null) {
                return result.fail().setMsg("收货地址不存在");
            }

            if (params.isDefaultAddress()) {
                DeliveryAddress oldDefault = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(member.getId()).and(QDeliveryAddress.deliveryAddress.defaultAddress.eq(true).and(QDeliveryAddress.deliveryAddress.id.ne(params.getId()))), DeliveryAddress.class);
                if (oldDefault != null) {
                    deliveryAddressApplication.modify(params, oldDefault);
                    return result.ok();
                }
            }

            deliveryAddressApplication.modify(params);
            return result.ok();

        } catch (Exception e) {
            logger.error("[创建收货地址异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 设为默认地址
     *
     * @param request
     * @return
     */
    @PutMapping("/setDefault")
    public Result setDefault(HttpServletRequest request, @RequestBody DeliveryAddress params) {
        Result result = new Result();
        try {
            WebUser user = Securitys.user(request);

            DeliveryAddress deliveryAddress = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(user.getId()).and(QDeliveryAddress.deliveryAddress.id.eq(params.getId())), DeliveryAddress.class);
            if (deliveryAddress == null) {
                return result.fail().setMsg("收货地址不存在");
            }

            DeliveryAddress oldDefault = queryChannelService.findOne(QDeliveryAddress.deliveryAddress.member.id.eq(user.getId()).and(QDeliveryAddress.deliveryAddress.defaultAddress.eq(true).and(QDeliveryAddress.deliveryAddress.id.ne(params.getId()))), DeliveryAddress.class);
            if (oldDefault != null) {
                deliveryAddressApplication.setDefault(deliveryAddress, oldDefault);
            } else {
                deliveryAddressApplication.setDefault(deliveryAddress);
            }

            return result.ok();

        } catch (Exception e) {
            logger.error("[创建收货地址异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }


    /**
     * 获取省市区json数据
     *
     * @param response
     */
    @GetMapping("/json")
    public void writeJson(HttpServletResponse response) {

        try {
            JSONArray provincesJson = new JSONArray();
            List<MerchantFreightProvince> provinces = queryChannelService.queryAllEntity("select * from mall_merchant_freight_province", Collections.emptyMap(), MerchantFreightProvince.class);

            for (MerchantFreightProvince province : provinces) {
                JSONArray citysJson = new JSONArray();
                List<MerchantFreightCity> cities = queryChannelService.queryAllEntity("select * from mall_merchant_freight_city where provinceCode = :code ", ImmutableMap.of("code", province.getProvinceCode()), MerchantFreightCity.class);

                for (MerchantFreightCity city : cities) {

                    JSONObject cityJson = new JSONObject();
                    cityJson.put("name", city.getName());
                    cityJson.put("cityCode", city.getCityCode());

                    JSONArray areasJson = new JSONArray();
                    List<MerchantFreightArea> areas = queryChannelService.queryAllEntity("select * from mall_merchant_freight_area where cityCode = :code", ImmutableMap.of("code", city.getCityCode()), MerchantFreightArea.class);
                    for (MerchantFreightArea area : areas) {
                        JSONObject areaJson = new JSONObject();
                        areaJson.put("name", area.getName());
                        areaJson.put("areaCode", area.getAreaCode());
                        areasJson.add(areaJson);
                    }
                    cityJson.put("children", areasJson);
                    citysJson.add(cityJson);
                }

                JSONObject provinceJson = new JSONObject();
                provinceJson.put("name", province.getName());
                provinceJson.put("provinceCode", province.getProvinceCode());
                provinceJson.put("children", citysJson);
                provincesJson.add(provinceJson);
            }

            response.setContentType("application/json;charset=utf-8");
            IOUtils.write(provincesJson.toString(), response.getWriter());
        } catch (Exception e) {
            logger.error("[获取省市区json异常]", e);
        }
    }


}
